#ifndef CLIENTCALCULATOR_HPP
#define CLIENTCALCULATOR_HPP

#include <iostream>
#include "protocol.hpp"
#include <time.h>
#include <unistd.h>
#include "TcpSocket.hpp"
#include <cassert>

class TcpClient
{
public:
    TcpClient(std::string ip, uint16_t port) : ip_(ip), port_(port) {}
    ~TcpClient() {}

public:
    bool Init()
    {
        sock_.Socket();
        return true;
    }
    bool Start()
    {
        bool r = sock_.Connect(ip_, port_);
        if (!r)
            return false;

        srand(time(nullptr) ^ getpid());
        int cnt = 5;
        const std::string opers = "+_*?%^=!";
        std::cout << "It 's test for Cnt: " << cnt << std::endl;

        while (cnt--)
        {

            int num1 = rand() % 100 + 1;
            usleep(100);
            int num2 = rand() % 100 + 1;
            usleep(100);
            char op = opers[rand() % opers.size()];

            // 构造
            Request req(num1, num2, op);
            req.DebugPrint();

            // 序列化
            std::string package;
            req.Serialize(&package);

            // 封装报头
            package = Encode(package);

            std::cout << "The latest request was not sent : " << package << std::endl;

            // 写入请求
            write(sock_.GetFd(), package.c_str(), package.size());
            // write(sock_.GetFd(), package.c_str(), package.size());
            // write(sock_.GetFd(), package.c_str(), package.size());
            // write 返回值代表写了多少长度

            // 读取响应
            char buff[1280];
            std::string getresp;
            ssize_t n = read(sock_.GetFd(), buff, sizeof(buff));// 这里阻塞了
            std::string content;

            if (n > 0)
            {
                buff[n] = 0;
                getresp = buff;

                // 解包报头
                bool r = Decode(getresp, &content);
                assert(r);
                // 反序列化
                Response resp;
                r = resp.Deserialize(content);
                assert(r);
                resp.DebugPrint();
            }
            sleep(1);
        }

        return true;
    }

private:
    std::string ip_;
    uint16_t port_;
    NetSocket sock_;
};
#endif